import React from "react";
// 父子通信：利用props属性

//props是只读对象，可以传：
//数字，字符串，布尔值，数组，对象，函数，jsx

//函数式子组件SonF
// const Sonf = (props) => {
//   //使用props获取父组件传来的数据
//   return (
//     <>
//       <div>我是函数式子组件：{props.msg}</div>
//       <ul>
//         {props.list.map((item) => (
//           <li key={item}>{item}</li>
//         ))}
//       </ul>
//       <div>props传来的对象中的属性：{props.object.name}</div>
//       {props.AppJsx}
//       <button onClick={props.AppFn}>触发父组件传来的函数</button>
//     </>
//   );
// };

// props支持结构赋值
// const Sonf = (props) => {
//   //使用props获取父组件传来的数据
//   const { msg, list, object, AppJsx, AppFn } = props;
//   return (
//     <>
//       <div>我是函数式子组件：{msg}</div>
//       <ul>
//         {list.map((item) => (
//           <li key={item}>{item}</li>
//         ))}
//       </ul>
//       <div>props传来的对象中的属性：{object.name}</div>
//       {AppJsx}
//       <button onClick={AppFn}>触发父组件传来的函数</button>
//     </>
//   );
// };

//props解构赋值还可以这样写
const Sonf = ({ msg, list, object, AppJsx, AppFn, getSonfMsg }) => {
    //使用props获取父组件传来的数据

    const setMsg = () => {
        const data = "我是来自子组件的数据";
        //通过父组件传来的getSonfMsg回调函数向父组件传子组件的数据
        getSonfMsg(data);
    };
    return (
        <>
            <div>
                我是函数式子组件：
                {msg}
            </div>
            <ul>
                {list.map((item) => (
                    <li key={item}>{item}</li>
                ))}
            </ul>
            <div>
                props传来的对象中的属性：
                {object.name}
            </div>
            {AppJsx}
            <button onClick={AppFn}>触发父组件传来的函数</button>
            <button
                onClick={() =>
                    getSonfMsg("我是来自子组件的数据，现在到了父组件")
                }>
                向父组件传数据
            </button>
            <button onClick={setMsg}>向父组件传数据</button>
        </>
    );
};

//类子组件SonC
class SonC extends React.Component {
    render() {
        //使用this.props获取父组件传来的数据
        return (
            <div>
                我是类子组件：
                {this.props.msg}
            </div>
        );
    }
}

//父组件App
class App extends React.Component {
    state = {
        message: "this is 父组件的数据",
        list: [1, 2, 3],
        object: {
            name: "对象",
        },
    };
    Appfn = () => {
        alert("我是父组件传来的函数");
    };
    getSonfMsg = (sonMsg) => {
        alert(sonMsg);
    };
    render() {
        return (
            <div className='App'>
                <Sonf
                    msg={this.state.message}
                    list={this.state.list}
                    object={this.state.object}
                    AppJsx={<h1>我是父组件传来的JSX</h1>}
                    AppFn={this.Appfn}
                    getSonfMsg={this.getSonfMsg}></Sonf>
                <hr />
                <SonC msg={this.state.message}></SonC>
            </div>
        );
    }
}

export default App;

//父传子：属性
//子传父：回调函数 callback

/**
 * React组件的数据渲染是否被调用者的props完全控制，控制则为受控组件，否则非受控组件
 */
